// Copyright (C) 2010  Joan Puigcerver Perez, <joapuipe@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef __DATABASE_HPP__
#define __DATABASE_HPP__

#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <cstdlib>
#include <ctime>

#include <Movies.hpp>
#include <People.hpp>
#include <Filter.hpp>
#include <LogUtils.hpp>
#include <Config.hpp>
#include <DBUtils.hpp>

class Database {
private:
  std::ostream& logfile;
  ost::Mutex&  log_mutex;

  void PureBFS(const Person source, std::vector<uint32_t>& distances,
	       const uint32_t max_dist,
	       const Filter filter = Filter()) const;

public:
  Movies movies;
  People people;

  typedef std::pair<Link, Link> LinkPair;
  typedef std::list<Link> LinkList;
  typedef std::list<LinkPair> LinkPairList;
  typedef std::list<Person> PersonList;
  /** The return type for the Distance request. */
  typedef std::pair<uint32_t,LinkPairList> DistanceResult;

  /** 
   * Constructor.
   *
   * @param logf Output stream used to print log messages.
   * @param logm Mutex to control the access to logf.
   */
  Database(std::ostream& logf = std::cout, ost::Mutex& logm = LOGmutex); 
  
  /**
   * Used to search a person in the database. It receives a name.
   *
   * If the exacte name is found, the first field of the returned pair it's set to true, if not it is set to false.
   * The second field of the returned pair is the list of persons that have a similar name for the given one.
   *
   * @param name Person's name or aka name.
   */
  std::pair< bool, std::list<const Person> > search_person(const std::string& name) const;
  
  /**
   * This function computes the minimum distance and the path between two persons using a filter.
   * A DistanceResult object is returned.
   * 
   * @param source Initial person.
   * @param target Last person.
   * @param filter Filtering options.
   */
  DistanceResult distance(const Person source, const Person target, 
			  const Filter filter = Filter()) const;  
  
  /**
   * This function is used to compute the average number of hops for a given person using some filtering options.
   *
   * @param source Initial person.
   * @param filter Filtering options.
   */
  float center(const Person source, const Filter filter = Filter()) const;
  
  /**
   * This function is used to obtain a list of persons who are at a distance of N hops from a given one.
   *
   * @param source Initial person.
   * @param dist Distance (number of hops).
   * @param filter Filtering options.
   */
  /*  PersonList distance_n(const Person source, const uint32_t dist, 
      const Filter filter = Filter()) const;*/

};



#endif
